import seaborn as sns
import matplotlib.pyplot as plt
from scipy.special import comb
import numpy as np
import pandas as pd
from scipy.stats import norm
from scipy.stats import t
import math
import sympy
import os
def Cost_curve():
    X = [0.1 * i for i in range(11)]
    P_cost = []
    FPR = [0, 0, 0.25, 0.25, 0.5, 0.75, 0.75, 1]
    TPR = [0, 0.25, 0.25, 0.5, 0.75, 0.75, 1, 1]
    One = [1 for i in range(len(TPR))]
    FNR = list(map(lambda x: x[0] - x[1], zip(One, TPR)))
    COST_01 = 3
    COST_10 = 1
    cost_norm = []
    weighted_FNR = [i * COST_01 for i in FNR]
    weighted_FPR = [i * COST_10 for i in FPR]
    Zero = [0 for i in range(len(weighted_FNR))]
    # for i in ordinate:
    plt.figure()
    for i in range(len(FPR)):
        X = [Zero[i], One[i]]
        Y = [weighted_FPR[i], weighted_FNR[i]]
        sns.lineplot(x=X, y=Y)
    plt.annotate('FPR', xy=(0, 0.5))
    plt.annotate('FNR', xy=(1, 0.5))
    plt.xlabel("归一化代价", fontproperties="Simsun")
    plt.ylabel("正例概率代价", fontproperties="Simsun")
    plt.show()

def Binary_dist():

    # 假设模型在全部数据上错误的概率为
    E_all = 0.3
    # 测试集T的样本量
    m_T = 10
    # 模型在T上面判断错误的数量
    m_T_Error = 6
    # 模型在T上的错误率
    e = round(m_T_Error/m_T,4)

    # 计算出现这种情况的概率
    def calculate_p(m_T,m_T_Error):
        p = (comb(m_T,m_T_Error) * (E_all ** m_T_Error)*(1-E_all)**(m_T-m_T_Error))
        return p
    # 出现每种情况的概率
    def calculate_ps(m_T):
        m_T_Errors = list(range(m_T + 1))
        ps = []
        for i in range(len(m_T_Errors)):
            m_T_Error = m_T_Errors[i]
            p = calculate_p(m_T,m_T_Error)
            ps.append(p)
        return m_T_Errors,ps
    m_T_Errors, ps = calculate_ps(m_T)
    def plot_scatter(x,y):
        _,ax1 = plt.subplots(figsize=(12,8))
        clrs = ['grey' for i in range(len(x))]
        sns.barplot(x,y,palette=clrs)
        ax1.set_xlabel("误分类样本数", fontproperties="Simsun")
        ax1.set_ylabel('概率',fontproperties="Simsun")
        ax1.tick_params('y',labelsize = 12)
        ax2 = ax1.twinx()
        sns.kdeplot(x,cumulative=True)
        plt.plot([7, 7, 7, 7], [-0.01, 0.25, 0.75, 1.01], linestyle='--', linewidth=2)
        plt.plot([7.5, 7.5, 7.5, 7.5], [-0.01, 0.25, 0.75, 1.01], linestyle='--', linewidth=2)
        plt.plot([8, 8, 8, 8], [-0.01, 0.25, 0.75, 1.01], linestyle='--', linewidth=2)
        plt.annotate(chr(945),xy=(7.5,0.0),fontsize = 20,color = 'green')
        ax2.set_ylabel("CDF")
        ax1.tick_params('y', labelsize=12)

        plt.show()
        return
    plot_scatter(m_T_Errors,ps)

def t_dist():
    print('比较t-分布与标准正态分布')
    x = np.linspace(-10, 10, 10000)
    # plt.plot(x, t.pdf(x, 1), label='df=1')
    # plt.plot(x, t.pdf(x, 2), label='df=20')
    # plt.plot(x, t.pdf(x, 100), label='df=100')
    plt.plot(x,t.pdf(x,0.75))
    plt.ylabel("概率密度", fontproperties="Simsun")
    plt.legend()
    plt.show()

def friedmantest():
    # 临界值域
    CD = 1.657
    cd = int(CD * 1000 // 2)
    # 平均序值
    order_value = [1,2.125,2.875]
    order_value_y = [0.75,0.5,0.25]
    m = []
    n = []
    f = []
    for order,i in enumerate(order_value):
        # print(i,int(i*10000 -cd),int(i * 1000 + cd + 1))
        m.append([i*0.001 for i in range(int(i*1000 -cd), int(i * 1000 + cd + 1))])
        # print(len(m[order]))
        f.append([(3- order) *0.25 for i in range(len(m[order]))])
        if order == 0:
            n.append(['Algorithm A' for i in range(len(m[order]))])
        elif order ==1:
            n.append(['Algorithm B' for i in range(len(m[order]))])
        else:
            n.append(['Algorithm C' for i in range(len(m[order]))])

    Data = pd.DataFrame()
    Data['Average Comparison Order Value'] = m[0]+m[1]+m[2]
    Data['Y_Data'] = f[0] + f[1] + f[2]
    Data['Algorithm'] = n[0]+n[1]+n[2]
    clrs = ['grey' for i in range(len(Data['Average Comparison Order Value']))]
    sns.lineplot(x = Data['Average Comparison Order Value'], y = Data['Y_Data'], hue = Data['Algorithm'], data=Data, color = 'grey')
    for order,i in enumerate(order_value):
        plt.plot(i,order_value_y[order],marker='o', markersize = 8, color = 'grey')
    plt.plot([CD,CD,CD,CD],[0,0.25,0.5,0.77],linestyle = '--', linewidth = 2)
    plt.yticks([])
    plt.show()

def Generalized_Error():
    pass

def log_Linear_Regression():
    X = [i*0.001 for i in range(0,2100)]
    Y = [1* i + 2 for i in X]
    exp_Y = [np.exp(i) for i in Y]
    sns.lineplot(x=X,y=Y)
    sns.lineplot(x=X,y=exp_Y)
    X_dot = [0.2,1,1.4]
    Y_dot = [1*i +2 for i in X_dot]
    exp_Y_dot = [np.exp(i) for i in Y_dot]
    for order,i in enumerate(X_dot):
        plt.plot(i,exp_Y_dot[order], marker='o', markersize=8, color='grey')
        plt.plot(i,Y_dot[order], marker='o', markersize=8, color='grey')
        plt.plot([i,i],[0,exp_Y_dot[order]],linestyle = '--', linewidth = 2, color = 'grey')
        plt.plot([0, i], [exp_Y_dot[order], exp_Y_dot[order]], linestyle='--', linewidth=1, color='grey')
    plt.plot([0, 0.2], [Y_dot[0], Y_dot[0]], linestyle='--', linewidth=1, color='grey')
    plt.annotate("$(x_1,y_1)$",xy=(0.2,np.exp(0.2+2)))
    plt.annotate("$(x_2,y_2)$", xy=(1, np.exp(1+ 2) ))
    plt.annotate("$(x_3,y_3)\\ y = e^{w^Tx+b}$", xy=(1.4, np.exp(1.4 + 2)))
    plt.annotate("$(x_1,y_1^{'})$", xy=(0.2,0.2+2))
    plt.annotate("$(x_2,y_2^{'})$", xy=(1, 1 + 2))
    plt.annotate("$(x_3,y y_3^{'})\\ y^{'}= w^Tx+b$", xy=(1.4, 1.4 + 2))
    plt.show()

def logit_regression():
    ax = plt.gca()
    z = [i * 0.01 for i in range(-1100,1100)]
    y = [1/(1+np.exp(-i)) for i in z]
    sns.lineplot(x= z, y = y)
    plt.plot(z[:1100],[0 for i in range(len(z[:1100]))],linewidth=2, color='red')
    plt.plot(z[-1100:], [1 for i in range(len(z[-1100:]))], linewidth=2, color='red')
    plt.plot(0,0.5, marker='o', markersize=8, color='red')
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')
    ax.spines['left'].set_position(('data', 0))
    ax.spines['bottom'].set_position(('data', 0))
    plt.show()
# friedmantest()
# Binary_dist()
# log_Linear_Regression()
# logit_regression()


# # print((9/15)*math.log(9/15) + (6/15)*math.log(6/15))
# Gain_a = -((9/15)*(math.log(9/15)/math.log(2)) + (6/15)*(math.log(6/15)/math.log(2)))
# IV_a= math.log(3)/math.log(2)
# # print(Gain_a,IV_a,Gain_a/IV_a)
#
# Ent = -(13/17)*((8/13)*(math.log(8/13)/math.log(2)) + (5/13)*(math.log(5/13)/math.log(2)))
# print(0.998 - Ent,Ent)


def GetUglyNumber_Solution(index):
    pass

print(GetUglyNumber_Solution(index =11))

# seq1 = ['fpp', 'cpp','lpp']
# seq2 = ['one','two','three']
# for i, (a,b) in enumerate(zip(seq1,seq2)):
#     print('{},{},{}'.format(i,a,b))

basedir = os.path.dirname(__file__)
print(basedir)